/**
 * PHOSIDE: PHosphorylation Site IDentification Engine.
 * Copyright 2009 Digital Biology Lab, University of Missouri.
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version. <p/> This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more
 * details.
 */

package phoside.miscellaneous.test;

import java.io.File;
import java.io.IOException;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import phoside.PhosideInit;
import phoside.PhosphoProteins;
import phoside.PhosphoProteinsImpl;

import phoside.io.ProteinsReader;
import phoside.io.xml.PhosideXmlProteinsReader;
import phoside.io.xml.PhosphoProteinFieldValueFormatter;

import phoside.ui.TrainingOptionDialog;

import phoside.ui.task.ProteinsReadTask;

import phoside.util.FileExtensionsFilter;
import phoside.util.FilePathParser;

/**
 *
 * @author gjj
 */
public class PhosideTestDialog extends javax.swing.JDialog {

    /** Creates new form PhosideTrainDialog */
    public PhosideTestDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        buttonGroup1 = new javax.swing.ButtonGroup();
        buttonGroup2 = new javax.swing.ButtonGroup();
        buttonGroup3 = new javax.swing.ButtonGroup();
        xmlPanel = new javax.swing.JPanel();
        javax.swing.JPanel xmlFilePanel = new javax.swing.JPanel();
        javax.swing.JPanel trainXmlFilePanel = new javax.swing.JPanel();
        trainXmlFileTextField = new javax.swing.JTextField();
        javax.swing.JButton trainXmlFileButton = new javax.swing.JButton();
        javax.swing.JPanel optionPanel = new javax.swing.JPanel();
        javax.swing.JButton optionBtn = new javax.swing.JButton();
        javax.swing.JPanel OKPanel = new javax.swing.JPanel();
        OKBtn = new javax.swing.JButton();
        javax.swing.JButton cancelBtn = new javax.swing.JButton();
        javax.swing.JPanel aatypePanel = new javax.swing.JPanel();
        kfoldPanel = new javax.swing.JPanel();
        javax.swing.JLabel kfoldLabel = new javax.swing.JLabel();
        kfoldTextField = new javax.swing.JTextField();
        javax.swing.JLabel repeatLabel = new javax.swing.JLabel();
        repeatTextField = new javax.swing.JTextField();
        javax.swing.JLabel repeatTimesLabel = new javax.swing.JLabel();
        typePanel = new javax.swing.JPanel();
        crossValidationRadioButton = new javax.swing.JRadioButton();
        looRadioButton = new javax.swing.JRadioButton();
        selfTrainingRadioButton = new javax.swing.JRadioButton();
        negSizePanel = new javax.swing.JPanel();
        sameSizeNegRadioButton = new javax.swing.JRadioButton();
        samePercentageRadioButton = new javax.swing.JRadioButton();
        javax.swing.JPanel targetPanel = new javax.swing.JPanel();
        javax.swing.JPanel targetFilePanel = new javax.swing.JPanel();
        targetFileTextField = new javax.swing.JTextField();
        javax.swing.JButton targetFileButton = new javax.swing.JButton();
        negDataPanel = new javax.swing.JPanel();
        javax.swing.JPanel negFromOtherFilePanel = new javax.swing.JPanel();
        negFromTrainFileRadioButton = new javax.swing.JRadioButton();
        negFromValidFileRadioButton = new javax.swing.JRadioButton();
        negFileTextField = new javax.swing.JTextField();
        negFileButton = new javax.swing.JButton();
        javax.swing.JPanel negValidSizePanel = new javax.swing.JPanel();
        negValidSizeTextField = new javax.swing.JTextField();
        javax.swing.JLabel numValidSizeNoteLabel = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("PHOSIDE train");
        getContentPane().setLayout(new java.awt.GridBagLayout());

        xmlPanel.setLayout(new java.awt.GridBagLayout());

        xmlFilePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Training file in XML format"));
        xmlFilePanel.setMinimumSize(new java.awt.Dimension(400, 63));
        xmlFilePanel.setPreferredSize(new java.awt.Dimension(500, 63));
        xmlFilePanel.setLayout(new java.awt.GridBagLayout());

        trainXmlFilePanel.setLayout(new java.awt.GridBagLayout());

        trainXmlFileTextField.setToolTipText("Please select a FASTA training file");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        trainXmlFilePanel.add(trainXmlFileTextField, gridBagConstraints);

        trainXmlFileButton.setText("Open");
        trainXmlFileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                trainXmlFileButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        trainXmlFilePanel.add(trainXmlFileButton, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        xmlFilePanel.add(trainXmlFilePanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        xmlPanel.add(xmlFilePanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        getContentPane().add(xmlPanel, gridBagConstraints);

        optionBtn.setText("Advanced options");
        optionBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                optionBtnActionPerformed(evt);
            }
        });
        optionPanel.add(optionBtn);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 10;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(optionPanel, gridBagConstraints);

        OKBtn.setText("   OK   ");
        OKBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                OKBtnActionPerformed(evt);
            }
        });
        OKPanel.add(OKBtn);

        cancelBtn.setText("Cancel");
        cancelBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelBtnActionPerformed(evt);
            }
        });
        OKPanel.add(cancelBtn);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 10;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(OKPanel, gridBagConstraints);

        aatypePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Types of sites"));
        aatypePanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 10, 5));

        aaTypeButtons = new LinkedHashMap();
        for (phoside.PhosphoProteins.PhosphoType phosphoType : phoside.PhosphoProteins.PhosphoType.values()) {
            javax.swing.JCheckBox cb = new javax.swing.JCheckBox(phosphoType.toString());
            aatypePanel.add(cb);
            aaTypeButtons.put(phosphoType, cb);
        }

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(aatypePanel, gridBagConstraints);

        kfoldPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Kfold cross validation"));
        kfoldPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        kfoldLabel.setText("K: ");
        kfoldPanel.add(kfoldLabel);

        kfoldTextField.setText("10");
        kfoldTextField.setMinimumSize(new java.awt.Dimension(50, 19));
        kfoldTextField.setPreferredSize(new java.awt.Dimension(50, 19));
        kfoldPanel.add(kfoldTextField);

        repeatLabel.setText("Repeat for ");
        kfoldPanel.add(repeatLabel);

        repeatTextField.setText("1");
        repeatTextField.setPreferredSize(new java.awt.Dimension(40, 19));
        kfoldPanel.add(repeatTextField);

        repeatTimesLabel.setText("times");
        kfoldPanel.add(repeatTimesLabel);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(kfoldPanel, gridBagConstraints);

        //typePanel.setVisible(false);
        typePanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        buttonGroup1.add(crossValidationRadioButton);
        crossValidationRadioButton.setSelected(true);
        crossValidationRadioButton.setText("K Cross Validation");
        crossValidationRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                crossValidationRadioButtonActionPerformed(evt);
            }
        });
        typePanel.add(crossValidationRadioButton);

        buttonGroup1.add(looRadioButton);
        looRadioButton.setText("Leave-one-out Validation");
        looRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                looRadioButtonActionPerformed(evt);
            }
        });
        typePanel.add(looRadioButton);

        buttonGroup1.add(selfTrainingRadioButton);
        selfTrainingRadioButton.setText("Self Training");
        selfTrainingRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                selfTrainingRadioButtonActionPerformed(evt);
            }
        });
        typePanel.add(selfTrainingRadioButton);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        getContentPane().add(typePanel, gridBagConstraints);

        negSizePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Negative test data size"));
        negSizePanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        buttonGroup2.add(sameSizeNegRadioButton);
        sameSizeNegRadioButton.setSelected(true);
        sameSizeNegRadioButton.setText("Same size as positive test data");
        negSizePanel.add(sameSizeNegRadioButton);

        buttonGroup2.add(samePercentageRadioButton);
        samePercentageRadioButton.setText("Same percentage as positive test data");
        negSizePanel.add(samePercentageRadioButton);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(negSizePanel, gridBagConstraints);

        targetPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Save to "));
        targetPanel.setMinimumSize(new java.awt.Dimension(400, 63));
        targetPanel.setPreferredSize(new java.awt.Dimension(500, 63));
        targetPanel.setLayout(new java.awt.GridBagLayout());

        targetFilePanel.setLayout(new java.awt.GridBagLayout());

        targetFileTextField.setToolTipText("Please select a FASTA training file");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        targetFilePanel.add(targetFileTextField, gridBagConstraints);

        targetFileButton.setText("Open");
        targetFileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                targetFileButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        targetFilePanel.add(targetFileButton, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        targetPanel.add(targetFilePanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(targetPanel, gridBagConstraints);

        negDataPanel.setVisible(false);
        negDataPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Negative data"));
        negDataPanel.setLayout(new java.awt.GridBagLayout());

        negFromOtherFilePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Select negative validation data from"));
        negFromOtherFilePanel.setLayout(new java.awt.GridBagLayout());

        buttonGroup3.add(negFromTrainFileRadioButton);
        negFromTrainFileRadioButton.setSelected(true);
        negFromTrainFileRadioButton.setText("Training file");
        negFromTrainFileRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                negFromTrainFileRadioButtonActionPerformed(evt);
            }
        });
        negFromOtherFilePanel.add(negFromTrainFileRadioButton, new java.awt.GridBagConstraints());

        buttonGroup3.add(negFromValidFileRadioButton);
        negFromValidFileRadioButton.setText("A validation file");
        negFromValidFileRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                negFromValidFileRadioButtonActionPerformed(evt);
            }
        });
        negFromOtherFilePanel.add(negFromValidFileRadioButton, new java.awt.GridBagConstraints());

        negFileTextField.setVisible(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        negFromOtherFilePanel.add(negFileTextField, gridBagConstraints);

        negFileButton.setVisible(false);
        negFileButton.setText("Open");
        negFileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                negFileButtonActionPerformed(evt);
            }
        });
        negFromOtherFilePanel.add(negFileButton, new java.awt.GridBagConstraints());

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        negDataPanel.add(negFromOtherFilePanel, gridBagConstraints);

        negValidSizePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("No. of negarive validation sites"));
        negValidSizePanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        negValidSizeTextField.setText("1000");
        negValidSizeTextField.setPreferredSize(new java.awt.Dimension(60, 19));
        negValidSizePanel.add(negValidSizeTextField);

        numValidSizeNoteLabel.setText("Put -1 to use all");
        negValidSizePanel.add(numValidSizeNoteLabel);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        negDataPanel.add(negValidSizePanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(negDataPanel, gridBagConstraints);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void optionBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optionBtnActionPerformed
        TrainingOptionDialog srcConfDialog = new TrainingOptionDialog(this, true);
        srcConfDialog.setLocationRelativeTo(this);
        srcConfDialog.setVisible(true);
}//GEN-LAST:event_optionBtnActionPerformed

    private void cancelBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelBtnActionPerformed
        setVisible(false);
        dispose();
}//GEN-LAST:event_cancelBtnActionPerformed

    private void OKBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_OKBtnActionPerformed
        if (!verifyInput())
            return;

        final cytoscape.task.ui.JTaskConfig jTaskConfig = new cytoscape.task.ui.JTaskConfig();
        jTaskConfig.setOwner(this.getParent());
        jTaskConfig.displayCloseButton(true);
        jTaskConfig.displayCancelButton(false);
        jTaskConfig.displayStatus(true);
        jTaskConfig.setAutoDispose(true);
        jTaskConfig.setMillisToPopup(100);

        //Reading phospho data
        PhosphoProteins phosphoData = new PhosphoProteinsImpl();
        ProteinsReader phosphoReader = new PhosideXmlProteinsReader(
                        trainXmlFileTextField.getText(), phosphoData,
                        new PhosphoProteinFieldValueFormatter());
               

        ProteinsReadTask phosphoReadTask = new ProteinsReadTask(phosphoReader);
        cytoscape.task.util.TaskManager.executeTask(phosphoReadTask, jTaskConfig);
        if (!phosphoReadTask.success()) {
            JOptionPane.showMessageDialog(this, "Failed to read the training file");
            return;
        }

        // train
        //ModelParameter param = getModelParameter();
        Set<PhosphoProteins.PhosphoType> types = new LinkedHashSet();
        for (PhosphoProteins.PhosphoType type : aaTypeButtons.keySet()) {
            if (aaTypeButtons.get(type).isSelected()) {
                types.add(type);
            }
        }

        int kfold = Integer.parseInt(kfoldTextField.getText());
        if (selfTrainingRadioButton.isSelected())
            kfold = 1;

        int repeat = Integer.parseInt(this.repeatTextField.getText());

        PhosideTestTask testTask;
        if (this.crossValidationRadioButton.isSelected() || this.selfTrainingRadioButton.isSelected())
            testTask = new PhosideTestTask(phosphoData, types, PhosideInit.trainingProps, kfold, repeat, sameSizeNegRadioButton.isSelected());
        else {
            PhosphoProteins negValidData = null;
            if (this.negFromValidFileRadioButton.isSelected()) {
                negValidData = new PhosphoProteinsImpl();
                phosphoReader = new PhosideXmlProteinsReader(
                        this.negFileTextField.getText(), negValidData,
                        new PhosphoProteinFieldValueFormatter());

                phosphoReadTask = new ProteinsReadTask(phosphoReader);
                cytoscape.task.util.TaskManager.executeTask(phosphoReadTask, jTaskConfig);
                if (!phosphoReadTask.success()) {
                    JOptionPane.showMessageDialog(this, "Failed to read the training file");
                    return;
                }
            }


            int nNegValid = Integer.parseInt(negValidSizeTextField.getText());
            testTask = new PhosideTestTask(phosphoData, negValidData, types, PhosideInit.trainingProps,nNegValid);
        }
        cytoscape.task.util.TaskManager.executeTask(testTask, jTaskConfig);
        if (!testTask.success()) {
            JOptionPane.showMessageDialog(this, "Failed to train the model.");
            return;
        }

        Object obj = testTask.getResultObject();
        if (obj==null) {
            JOptionPane.showMessageDialog(this, "Failed to train the model.");
            return;
        }

        // save the model
        String dirResult = targetFileTextField.getText();
        
        List<String> strsRes = new ArrayList();

        if (this.crossValidationRadioButton.isSelected() || this.selfTrainingRadioButton.isSelected()) {
            double[][][] result = (double[][][])obj;
            for (int irepeat=0; irepeat<result.length; irepeat++) {
                for (int ifold=0; ifold<result[irepeat].length; ifold++) {
                    StringBuilder sb = new StringBuilder();
                    for (int j=0; j<result[irepeat][ifold].length; j++) {
                        sb.append(result[irepeat][ifold][j]+"\t");
                    }
                    strsRes.add(sb.toString());
                }
            }
        } else {
            double[][] result = (double[][])obj;
            for (int i=0; i<result.length; i++) {
                strsRes.add(result[i][0]+"\t"+result[i][1]);
            }

            double area = 0;
            int n = result.length;
            for (int i=0; i<n-1; i++) {
                area += 0.5*(result[i][1]+result[i+1][1])
                        *(result[i+1][0]-result[i][0]);
            }
            System.out.println(area);
        }

        try {
            phoside.util.IOUtil.writeCollectionAscii(strsRes, dirResult);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Failed to save the result.");
            return;
        }
        
        succ = true;
//        this.setVisible(false);
//        this.dispose();

        JOptionPane.showMessageDialog(this, "Model trained successfully.");
}//GEN-LAST:event_OKBtnActionPerformed

    private void trainXmlFileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_trainXmlFileButtonActionPerformed
        JFileChooser fc = new JFileChooser(PhosideInit.defaultPath);
        ArrayList<String> exts = new ArrayList<String>(1);
        String ext = "xml";
        exts.add(ext);
        fc.setFileFilter(new FileExtensionsFilter(exts,"XML file (.xml)"));
        //fc.setAcceptAllFileFilterUsed(true);
        fc.setDialogTitle("Select a XML file...");
        int returnVal = fc.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            PhosideInit.defaultPath = file.getParent();

            String filePath = PhosideInit.defaultPath + File.separator + file.getName();
            trainXmlFileTextField.setText(filePath);

            String fileName = FilePathParser.getName(filePath);
            targetFileTextField.setText(PhosideInit.defaultPath+File.separator+fileName+"-test.txt");
        }
    }//GEN-LAST:event_trainXmlFileButtonActionPerformed

    private void targetFileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_targetFileButtonActionPerformed
        JFileChooser fc;
        String defFile = targetFileTextField.getText();
        if (defFile.length()>0) {
            fc = new JFileChooser(FilePathParser.getDir(defFile));
        } else {
            fc = new JFileChooser(PhosideInit.defaultPath);
        }

        String ext = "txt";
        fc.setSelectedFile(new File(defFile));
        ArrayList<String> exts = new ArrayList<String>(1);
        exts.add(ext);
        fc.setFileFilter(new FileExtensionsFilter(exts,"Text file (.txt)"));
        //fc.setAcceptAllFileFilterUsed(true);
        fc.setDialogTitle("Save to...");
        int returnVal = fc.showSaveDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            PhosideInit.defaultPath = file.getParent();

            String filePath = PhosideInit.defaultPath + File.separator + file.getName();
            targetFileTextField.setText(filePath);
        }
}//GEN-LAST:event_targetFileButtonActionPerformed

    private void negFromTrainFileRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_negFromTrainFileRadioButtonActionPerformed
        negFileTextField.setVisible(false);
        negFileButton.setVisible(false);
    }//GEN-LAST:event_negFromTrainFileRadioButtonActionPerformed

    private void negFromValidFileRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_negFromValidFileRadioButtonActionPerformed
        negFileTextField.setVisible(true);
        negFileButton.setVisible(true);
    }//GEN-LAST:event_negFromValidFileRadioButtonActionPerformed

    private void negFileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_negFileButtonActionPerformed
                JFileChooser fc = new JFileChooser(PhosideInit.defaultPath);
        ArrayList<String> exts = new ArrayList<String>(1);
        String ext = "xml";
        exts.add(ext);
        fc.setFileFilter(new FileExtensionsFilter(exts,"XML file (.xml)"));
        //fc.setAcceptAllFileFilterUsed(true);
        fc.setDialogTitle("Select a XML file...");
        int returnVal = fc.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            PhosideInit.defaultPath = file.getParent();

            String filePath = PhosideInit.defaultPath + File.separator + file.getName();
            negFileTextField.setText(filePath);
        }
    }//GEN-LAST:event_negFileButtonActionPerformed

    private void crossValidationRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_crossValidationRadioButtonActionPerformed
        this.kfoldPanel.setVisible(true);
        this.negSizePanel.setVisible(true);
        this.negDataPanel.setVisible(false);
        this.pack();
    }//GEN-LAST:event_crossValidationRadioButtonActionPerformed

    private void looRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_looRadioButtonActionPerformed
        this.kfoldPanel.setVisible(false);
        this.negSizePanel.setVisible(false);
        this.negDataPanel.setVisible(true);
        this.pack();
    }//GEN-LAST:event_looRadioButtonActionPerformed

    private void selfTrainingRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selfTrainingRadioButtonActionPerformed
        this.kfoldPanel.setVisible(false);
        this.negSizePanel.setVisible(true);
        this.negDataPanel.setVisible(false);
        this.pack();
    }//GEN-LAST:event_selfTrainingRadioButtonActionPerformed

    private boolean verifyInput() {
        Set<PhosphoProteins.PhosphoType> types = new LinkedHashSet();
        for (PhosphoProteins.PhosphoType type : aaTypeButtons.keySet()) {
            if (aaTypeButtons.get(type).isSelected()) {
                types.add(type);
            }
        }

        if (types.isEmpty()) {
            JOptionPane.showMessageDialog(this, "Error: select at least one type of amino acid.");
            return false;
        }

        String strK = this.kfoldTextField.getText();
        if (strK.length()==0) {
            JOptionPane.showMessageDialog(this, "Error: input K.");
            return false;
        }

        String strTime = this.repeatTextField.getText();
        if (strTime.length()==0) {
            JOptionPane.showMessageDialog(this, "Error: input repeat time.");
            return false;
        }

        int k;
        try {
            k = Integer.valueOf(strK);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Error: K must be an integer.");
            return false;
        }

        if (k<1) {
            JOptionPane.showMessageDialog(this, "Error: K must be larger than or equal to 1.");
            return false;
        }

        int t;
        try {
            t = Integer.valueOf(strTime);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Error: time must be an integer.");
            return false;
        }

        if (t<1) {
            JOptionPane.showMessageDialog(this, "Error: K must be larger than or equal to 2.");
            return false;
        }

        if (trainXmlFileTextField.getText().length()==0) {
            JOptionPane.showMessageDialog(this, "Error: specify a XML file containing the protein sequences.");
            return false;
        }

        return true;
    }

    public boolean success() {
        return succ;
    }

    public static void main(String[] args) {
        PhosideTestDialog dialog = new PhosideTestDialog(new java.awt.Frame(), false);
        dialog.setVisible(true);
    }

    private boolean succ = false;
    private Map<PhosphoProteins.PhosphoType, javax.swing.JCheckBox> aaTypeButtons;

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton OKBtn;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.ButtonGroup buttonGroup2;
    private javax.swing.ButtonGroup buttonGroup3;
    private javax.swing.JRadioButton crossValidationRadioButton;
    private javax.swing.JPanel kfoldPanel;
    private javax.swing.JTextField kfoldTextField;
    private javax.swing.JRadioButton looRadioButton;
    private javax.swing.JPanel negDataPanel;
    private javax.swing.JButton negFileButton;
    private javax.swing.JTextField negFileTextField;
    private javax.swing.JRadioButton negFromTrainFileRadioButton;
    private javax.swing.JRadioButton negFromValidFileRadioButton;
    private javax.swing.JPanel negSizePanel;
    private javax.swing.JTextField negValidSizeTextField;
    private javax.swing.JTextField repeatTextField;
    private javax.swing.JRadioButton samePercentageRadioButton;
    private javax.swing.JRadioButton sameSizeNegRadioButton;
    private javax.swing.JRadioButton selfTrainingRadioButton;
    private javax.swing.JTextField targetFileTextField;
    private javax.swing.JTextField trainXmlFileTextField;
    private javax.swing.JPanel typePanel;
    private javax.swing.JPanel xmlPanel;
    // End of variables declaration//GEN-END:variables

}
